package org.dxw.common.enums;

import cn.hutool.extra.spring.SpringUtil;
import com.sun.org.apache.bcel.internal.generic.NEW;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.dxw.service.OrderWideTableService;
import org.dxw.service.UserRoleMenuWideTableService;
import org.dxw.vo.TableChangeMsg;

import java.util.*;
import java.util.function.Function;

/**
 * @Author dxw
 * @Date 2023/11/19 14:55
 * @Description
 */
@Getter
public enum TableChangeEnum {

    USER_ROLE_MENU_TABLE_DATA_UPDATE,
    ORDER_WIDE_TALBE_DATA_UPDATE;
    //如果有其他的表变动，要执行某些逻辑的话，增加其他的类型

    public static final String INSERT = "INSERT";

    public static final String UPDATE = "UPDATE";

    public static final String DELETE = "INSERT";

    //key: 表名,changeType
    //value: consumer
    public static Map<String, Set<TableChangeEnum>> tableChangeTypeConsumerMap = new HashMap<>();

    static{
        {
            List<TableChangeVO> TableChangeVOList = Arrays.asList(
                    new TableChangeVO("sys_user", Arrays.asList(TableChangeEnum.INSERT
                            , TableChangeEnum.UPDATE, TableChangeEnum.DELETE)),
                    new TableChangeVO("sys_role", Arrays.asList(TableChangeEnum.INSERT
                            , TableChangeEnum.UPDATE, TableChangeEnum.DELETE)),
                    new TableChangeVO("sys_menu", Arrays.asList(TableChangeEnum.INSERT
                            , TableChangeEnum.UPDATE, TableChangeEnum.DELETE))
            );
            USER_ROLE_MENU_TABLE_DATA_UPDATE.TableChangeVOList = TableChangeVOList;
            ORDER_WIDE_TALBE_DATA_UPDATE.supportRowsUpdate = false;
            USER_ROLE_MENU_TABLE_DATA_UPDATE.name = "USER_ROLE_MENU_TABLE_DATA_UPDATE";
            USER_ROLE_MENU_TABLE_DATA_UPDATE.consumer = (obj) ->{
                UserRoleMenuWideTableService bean = SpringUtil.getBean(UserRoleMenuWideTableService.class);
                return bean.updateData((List)obj);
            };
        }


        {
            List<TableChangeVO> tableChangeVOList = Arrays.asList(
                    new TableChangeVO("order", Arrays.asList(TableChangeEnum.INSERT
                            , TableChangeEnum.UPDATE, TableChangeEnum.DELETE)),
                    new TableChangeVO("store", Arrays.asList(TableChangeEnum.INSERT
                            , TableChangeEnum.UPDATE, TableChangeEnum.DELETE))
            );
            ORDER_WIDE_TALBE_DATA_UPDATE.TableChangeVOList = tableChangeVOList;
            ORDER_WIDE_TALBE_DATA_UPDATE.supportRowsUpdate = false;
            ORDER_WIDE_TALBE_DATA_UPDATE.name = "ORDER_WIDE_TALBE_DATA_UPDATE";
            ORDER_WIDE_TALBE_DATA_UPDATE.consumer = (obj) ->{
            OrderWideTableService bean = SpringUtil.getBean(OrderWideTableService.class);
            return bean.updateData((List)obj);
            };

        }

        /**---------------如果有其他的表变动，要执行某些逻辑的话，增加其他的类型begin--------------------*/





        /**---------------如果有其他的表变动，要执行某些逻辑的话，增加其他的类型end------ ---------------*/
        TableChangeEnum[] values = values();
        for (TableChangeEnum tableChangeEnum : values) {
            List<TableChangeVO> tableChangeVOList = tableChangeEnum.getTableChangeVOList();
            //拿到该枚举感兴趣的所有的表的操作
            List<String> keys = new ArrayList<>();
            for (TableChangeVO tableChangeVO : tableChangeVOList) {
                for (String s : tableChangeVO.getChangeTypes()) {
                    String key = buildTableNameAndTypeStr(tableChangeVO.getTableName(), s);
                    keys.add(key);
                }
            }

            //把该操作对应的 消费者放到set集合中
            for (String key : keys) {
                Set<TableChangeEnum> tableChangeEnumSet = tableChangeTypeConsumerMap.get(key);
                if(tableChangeEnumSet == null){
                    tableChangeEnumSet = new HashSet<>();
                    tableChangeTypeConsumerMap.put(key, tableChangeEnumSet);
                }
                tableChangeEnumSet.add(tableChangeEnum);
            }

        }

    }

    private String name;

    /**
     * 该枚举对应的表更新类型
     */
    private List<TableChangeVO> TableChangeVOList;

    /**
     * 该枚举对应的要处理的业务逻辑
     */
    private Function consumer;

    private Integer maxFailCount = 3;

    /**
     * 是否支持记录级别的更新
     */
    private boolean supportRowsUpdate;


    public static String buildTableNameAndTypeStr(String tableName, String changeType){
        return tableName + "," + changeType;
    }

    public static boolean isInterested(String tableName, String changeType){
        return tableChangeTypeConsumerMap.keySet().contains(buildTableNameAndTypeStr(tableName, changeType));
    }
    
    public static Set<TableChangeEnum> getConsumerSet(TableChangeMsg tableChangeMsg){
        Set<TableChangeEnum> tableChangeEnums = tableChangeTypeConsumerMap.get(buildTableNameAndTypeStr(tableChangeMsg.getTableName()
                , tableChangeMsg.getChangeType()));
        return tableChangeEnums;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class TableChangeVO{

        /**
         * 表名
         */
        private String tableName;

        /**
         * 操作类型，新增，修改，删除
         */
        private List<String> changeTypes;

    }

}
